package 正则表达式;

//捕获组捕获到的内容，不仅可以在正则表达式外部通过程序进行引用，也可以在正则表达式内部进行引用，这种引用方式就是反向引用。 要了解反向引用，首先要了解捕获组，
//关于捕获组，参考正则基础之——捕获组（capture group） 。 反向引用的作用通常是用来查找或限定重复、查找或限定指定标识配对出现等等。 普通捕获组反向引用
//中 number 是十进制的数字，即捕获组的编号；命名捕获组反向引用中的 name 为命名捕获组的组名。 捕获组 (Expression) 在匹配成功时，会将子表达式匹配到
//的内容，保存到内存中一个以数字编号的组里，可以简单的认为是对一个局部变量进行了赋值，这时就可以通过反向引用方式，引用这个局部变量的值。


//1.反向引用需要使用到分组，分组就是使用()括起来的部分为一个整体，在进行分组匹配时的原则是：由外向内，由左向右
//
//2.反向引用如:\1,\2等
// \1：表示的是引用第一次匹配到的()括起来的部分
// \2：表示的是引用第二次匹配到的()括起来的部分
//
// （1）例：
//      String regex = "^(\\d)\\1$";
//      首先这里是匹配两位，\d一位,\1又引用\d一位 这里的\1会去引用（\d）匹配到的内容，因为(\d)是第一次匹配到的内容。
//     如：str = "22"时，(\\d)匹配到2，所以\1引用(\\d)的值也为2，所以str="22"能匹配
//           str = "23"时，(\\d)匹配到2，因为\1引用(\\d)的值2,而这里是3，所以str="23"不能匹配
// （2）例：
//      String regex = "^(\\d)\\1[0-9](\d)\1{2}";
//      注意在后面第二个(\d)\1{2}中的\1，这里的\1并不会去匹配他前面的(\d)，而是匹配第一个(\\d),
//      如：第一个(\d)为3时，则第一个\1也为3，同样最后那个\1也为3，所以结果可以是335933,332533
//           而不是336444,339888
//
// （3）例：
//      String regex = " ^(\d)\1[0-9](\d)\2{2}$";
//      这里使用了\2引用第二次匹配到的分组，这里第二次匹配的分组为\2前面的(\d)， 这里的{2}指的是\2的值出现两次
//      如：第一个(\d)为4时，\1引用第1个(\d)也为4，第二个(\d)为5时，\2引用第二个(\d)为5，所以结果可以是:447555,440222
// 
// （4）例：
//      String regex = " ^((\d)3)\1[0-9](\d)\2{2}$";
//      当匹配中的分组有嵌套时，是从外向里匹配的，其次在由左向右匹配
//      这里主要是分析匹配到分组的顺序，首先匹配((\d)3)这整个部分，其次匹配((\d)3)里面的(\d)，第三次匹配时最后一个\2前面的(\d)
//      如：如((\d)3)中的(\d)为2时，((\d)3)的值为23，此时\1为((\d)3)的值1，而\2引用((\d)3)中的(\d)的值3，第三个(\d)为5时，此时\3引用
//      第三个(\d)的值5,所以结果可以有：23238522，23230522，

//import java.util.regex.Matcher;
//import java.util.regex.Pattern;          
public class 反向引用1 {
    public static void main(String[] args) {
    	String re1 = "^(\\d)\\1$";
    	System.out.println("22".matches(re1));//true
    	System.out.println("23".matches(re1));//false
    	
    	String re2 = "^(\\d)\\1[0-9](\\d)\\1{2}";
    	System.out.println("335933".matches(re2));//true
    	System.out.println("332533".matches(re2));//true
    	System.out.println("336444".matches(re2));//false
    	System.out.println("339888".matches(re2));//false
    	
    	String re3 = "^(\\d)\\1[0-9](\\d)\\2{2}$";
    	System.out.println("447555".matches(re3));//true
    	System.out.println("440222".matches(re3));//true
    	
    	String re4 ="^((\\d)3)\\1[0-9](\\d)\\2{2}$";
    	System.out.println("23238522".matches(re4));//true
    	System.out.println("23230522".matches(re4));//true   	
    }
}

